cssprovider: Change declaration parsing for error reporting
authorBenjamin Otte <otte@redhat.com>
Thu, 7 Apr 2011 22:08:10 +0000 (00:08 +0200)
committerBenjamin Otte <otte@redhat.com>
Wed, 18 May 2011 19:58:44 +0000 (21:58 +0200)
Previously, we only checked for errors after parsing the full
declaration. Now we detect errors with the property before even
attempting to parse its value.
The benefit here is that the error reporting reports the correct line
and position numbers.

gtk/gtkcssprovider.c

index 13ee0fb0d85c68c2f57deb707e652b89598d4436..e0a42c734f234b2bd7412593e01dce0348e070ff 100644 (file)
@@ -3544,20 +3544,32 @@ parse_rule (GtkCssProvider  *css_provider,
     {
       gchar *value_str = NULL;
       GtkStylePropertyParser parse_func = NULL;
-      GParamSpec *pspec;
+      GParamSpec *pspec = NULL;;
       gchar *prop;
 
       prop = g_strdup (scanner->value.v_identifier);
+
+      if (!gtk_style_properties_lookup_property (prop, &parse_func, &pspec) &&
+          prop[0] != '-')
+        {
+          gtk_css_provider_error (css_provider,
+                                  GTK_CSS_PROVIDER_ERROR,
+                                  GTK_CSS_PROVIDER_ERROR_PROPERTY_NAME,
+                                  "'%s' is not a valid property name",
+                                  prop);
+          g_free (prop);
+          goto find_end_of_declaration;
+        }
+
       g_scanner_get_next_token (scanner);
 
       if (scanner->token != ':')
         {
           g_free (prop);
-          return ':';
+          gtk_css_provider_invalid_token (css_provider, "':'");
+          goto find_end_of_declaration;
         }
 
-      priv->value_pos = priv->scanner->text;
-
       css_provider_push_scope (css_provider, SCOPE_VALUE);
       g_scanner_get_next_token (scanner);
 
@@ -3572,7 +3584,7 @@ parse_rule (GtkCssProvider  *css_provider,
       SKIP_SPACES (value_str);
       g_strchomp (value_str);
 
-      if (gtk_style_properties_lookup_property (prop, &parse_func, &pspec))
+      if (pspec)
         {
           GValue *val;
 
@@ -3618,7 +3630,7 @@ parse_rule (GtkCssProvider  *css_provider,
               g_free (prop);
 
               gtk_css_provider_invalid_token (css_provider, "Property value");
-              return G_TOKEN_IDENTIFIER;
+              goto find_end_of_declaration;
             }
         }
       else if (prop[0] == '-')
@@ -3637,7 +3649,18 @@ parse_rule (GtkCssProvider  *css_provider,
       css_provider_pop_scope (css_provider);
       g_scanner_get_next_token (scanner);
 
-      if (scanner->token != ';')
+      if (scanner->token != ';' &&
+          scanner->token != G_TOKEN_RIGHT_CURLY)
+        {
+          gtk_css_provider_invalid_token (css_provider, "';'");
+        }
+
+find_end_of_declaration:
+      while (scanner->token != ';' &&
+             scanner->token != G_TOKEN_RIGHT_CURLY)
+        g_scanner_get_next_token (scanner);
+      
+      if (scanner->token == G_TOKEN_RIGHT_CURLY)
         break;
 
       g_scanner_get_next_token (scanner);
@@ -3652,6 +3675,20 @@ parse_rule (GtkCssProvider  *css_provider,
   return G_TOKEN_NONE;
 }
 
+static void
+gtk_css_provider_reset (GtkCssProvider *css_provider)
+{
+  GtkCssProviderPrivate *priv;
+
+  priv = css_provider->priv;
+
+  if (priv->selectors_info->len > 0)
+    g_ptr_array_remove_range (priv->selectors_info, 0, priv->selectors_info->len);
+
+  g_free (priv->filename);
+  priv->filename = NULL;
+}
+
 static gboolean
 parse_stylesheet (GtkCssProvider  *css_provider,
                   GError         **error)
@@ -3738,8 +3775,7 @@ gtk_css_provider_load_from_data (GtkCssProvider  *css_provider,
   if (length < 0)
     length = strlen (data);
 
-  if (priv->selectors_info->len > 0)
-    g_ptr_array_remove_range (priv->selectors_info, 0, priv->selectors_info->len);
+  gtk_css_provider_reset (css_provider);
 
   priv->scanner->input_name = "-";
   priv->buffer = data;
@@ -3787,10 +3823,8 @@ gtk_css_provider_load_from_file (GtkCssProvider  *css_provider,
       return FALSE;
     }
 
-  if (priv->selectors_info->len > 0)
-    g_ptr_array_remove_range (priv->selectors_info, 0, priv->selectors_info->len);
+  gtk_css_provider_reset (css_provider);
 
-  g_free (priv->filename);
   priv->filename = g_file_get_path (file);
 
   priv->scanner->input_name = priv->filename;
@@ -3836,10 +3870,7 @@ gtk_css_provider_load_from_path_internal (GtkCssProvider  *css_provider,
 
   if (reset)
     {
-      if (priv->selectors_info->len > 0)
-        g_ptr_array_remove_range (priv->selectors_info, 0, priv->selectors_info->len);
-
-      g_free (priv->filename);
+      gtk_css_provider_reset (css_provider);
       priv->filename = g_strdup (path);
     }